package com.hbb20;


import com.futuremind.recyclerviewfastscroll.ItemSizeProvider;
import com.futuremind.recyclerviewfastscroll.SectionTitleProvider;
import com.hbb20.utils.Log;
import com.hbb20.utils.SystemUtils;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.IDialog;
import ohos.app.Context;
import ohos.global.resource.Resource;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageInfo;
import ohos.media.image.common.Size;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hbb20 on 11/1/16.
 */
class CountryCodeAdapter extends RecycleItemProvider implements SectionTitleProvider, ItemSizeProvider {
    List<CCPCountry> filteredCountries = null, masterCountries = null;
    Text textView_noResult;
    CountryCodePicker codePicker;
    LayoutScatter inflater;
    TextField editText_search;
    IDialog dialog;
    Context context;
    DependentLayout rlQueryHolder;
    Image imgClearQuery;
    int preferredCountriesCount = 0;

    CountryCodeAdapter(Context context, List<CCPCountry> countries, CountryCodePicker codePicker, DependentLayout rlQueryHolder, final TextField editText_search, Text textView_noResult, IDialog dialog, Image imgClearQuery) {
        this.context = context;
        this.masterCountries = countries;
        this.codePicker = codePicker;
        this.dialog = dialog;
        this.textView_noResult = textView_noResult;
        this.editText_search = editText_search;
        this.rlQueryHolder = rlQueryHolder;
        this.imgClearQuery = imgClearQuery;
        this.inflater = LayoutScatter.getInstance(context);
        this.filteredCountries = getFilteredCountries("");
        setSearchBar();
    }


    @Override
    public Object getItem(int i) {
        return masterCountries != null ? masterCountries.get(i) : null;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
        CountryCodeViewHolder countryCodeViewHolder;
        if (component == null) {
            component = inflater.parse(ResourceTable.Layout_layout_recycler_country_tile, null, false);
            countryCodeViewHolder = new CountryCodeViewHolder(component);
            component.setTag(countryCodeViewHolder);
        } else {
            countryCodeViewHolder = (CountryCodeViewHolder) component.getTag();
        }
        onBindViewHolder(countryCodeViewHolder, i);

        return component;
    }

    private void setSearchBar() {
        if (codePicker.isSearchAllowed()) {
            imgClearQuery.setVisibility(Component.HIDE);
            setTextWatcher();
            setQueryClearListener();
        } else {
            rlQueryHolder.setVisibility(Component.HIDE);
        }
    }

    private void setQueryClearListener() {
        imgClearQuery.setClickedListener(component -> editText_search.setText(""));


    }

    /**
     * add textChangeListener, to apply new query each time editText get text changed.
     */
    private void setTextWatcher() {
        if (this.editText_search != null) {
            this.editText_search.addTextObserver(new Text.TextObserver() {
                @Override
                public void onTextUpdated(String s, int i, int i1, int i2) {
                    applyQuery(s);
                    if (s.trim().equals("")) {
                        imgClearQuery.setVisibility(Component.HIDE);
                    } else {
                        imgClearQuery.setVisibility(Component.VISIBLE);
                    }
                }
            });
            this.editText_search.setEditorActionListener(new Text.EditorActionListener() {
                @Override
                public boolean onTextEditorAction(int actionId) {
                    if (actionId == 3) {
                        return true;
                    }
                    return false;
                }
            });
        }
    }

    /**
     * Filter country list for given keyWord / query.
     * Lists all countries that contains @param query in country's name, name code or phone code.
     *
     * @param query : text to match against country name, name code or phone code
     */
    private void applyQuery(String query) {


        textView_noResult.setVisibility(Component.HIDE);
        query = query.toLowerCase();

        //if query started from "+" ignore it
        if (query.length() > 0 && query.charAt(0) == '+') {
            query = query.substring(1);
        }

        filteredCountries = getFilteredCountries(query);

        if (filteredCountries.size() == 0) {
            textView_noResult.setVisibility(Component.VISIBLE);
        }
        notifyDataChanged();
    }

    private List<CCPCountry> getFilteredCountries(String query) {
        List<CCPCountry> tempCCPCountryList = new ArrayList<CCPCountry>();
        preferredCountriesCount = 0;
        if (codePicker.preferredCountries != null && codePicker.preferredCountries.size() > 0) {
            for (CCPCountry CCPCountry : codePicker.preferredCountries) {
                if (CCPCountry.isEligibleForQuery(query)) {
                    tempCCPCountryList.add(CCPCountry);
                    preferredCountriesCount++;
                }
            }

            if (tempCCPCountryList.size() > 0) { //means at least one preferred country is added.
                CCPCountry divider = null;
                tempCCPCountryList.add(divider);
                preferredCountriesCount++;
            }
        }

        for (CCPCountry CCPCountry : masterCountries) {
            if (CCPCountry.isEligibleForQuery(query)) {
                tempCCPCountryList.add(CCPCountry);
            }
        }
        return tempCCPCountryList;
    }


    private void onBindViewHolder(CountryCodeViewHolder countryCodeViewHolder, final int i) {
        countryCodeViewHolder.setCountry(filteredCountries.get(i));
        if (filteredCountries.size() > i && filteredCountries.get(i) != null) {
            countryCodeViewHolder.getMainView().setClickedListener(component -> {
                if (filteredCountries != null && filteredCountries.size() > i) {
                    codePicker.onUserTappedCountry(filteredCountries.get(i));
                }
                if (component != null && filteredCountries != null && filteredCountries.size() > i && filteredCountries.get(i) != null) {
                    // InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                    //imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                    // dialog.dismiss();

                    dialog.destroy();
                }
            });
        } else {
            countryCodeViewHolder.getMainView().setClickedListener(null);
        }

    }


    @Override
    public String getSectionTitle(int position) {
        CCPCountry ccpCountry = filteredCountries.get(position);
        if (preferredCountriesCount > position) {
            return "★";
        } else if (ccpCountry != null) {
            return ccpCountry.getName().substring(0, 1);
        } else {
            return "☺"; //this should never be the case
        }
    }

    @Override
    public int getCount() {
        return filteredCountries != null ? filteredCountries.size() : 0;
    }

    @Override
    public int getItemHeight() {
        return (int) SystemUtils.vp2px(context, 50);
    }

    @Override
    public int getItemWidth() {
        return 0;
    }


    class CountryCodeViewHolder {
        Component relativeLayout_main;
        Text textView_name, textView_code;
        Image imageViewFlag;
        DirectionalLayout linearFlagHolder;
        Component divider;

        public CountryCodeViewHolder(Component itemView) {
            relativeLayout_main = itemView;
            textView_name = (Text) relativeLayout_main.findComponentById(ResourceTable.Id_textView_countryName);
            textView_code = (Text) relativeLayout_main.findComponentById(ResourceTable.Id_textView_code);
            imageViewFlag = (Image) relativeLayout_main.findComponentById(ResourceTable.Id_image_flag);
            linearFlagHolder = (DirectionalLayout) relativeLayout_main.findComponentById(ResourceTable.Id_linear_flag_holder);
            divider = relativeLayout_main.findComponentById(ResourceTable.Id_preferenceDivider);

            if (codePicker.getDialogTextColor() != 0) {
                Color color = new Color(codePicker.getDialogTextColor());
                textView_name.setTextColor(color);
                textView_code.setTextColor(color);
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(codePicker.getDialogTextColor()));
                divider.setBackground(shapeElement);
                //divider.setBackgroundColor(codePicker.getDialogTextColor());
            }

            try {
                if (codePicker.getDialogTypeFace() != null) {
                    textView_code.setFont(codePicker.getDialogTypeFace());
                    textView_name.setFont(codePicker.getDialogTypeFace());
                }
            } catch (Exception e) {
                Log.i("hh",e.getMessage());
            }
        }

        public void setCountry(CCPCountry ccpCountry) {
            if (ccpCountry != null) {
                divider.setVisibility(Component.HIDE);
                textView_name.setVisibility(Component.VISIBLE);
                textView_code.setVisibility(Component.VISIBLE);
                if (codePicker.isCcpDialogShowPhoneCode()) {
                    textView_code.setVisibility(Component.VISIBLE);
                } else {
                    textView_code.setVisibility(Component.HIDE);
                }

                String countryName = "";

                if (codePicker.getCcpDialogShowFlag() && codePicker.ccpUseEmoji) {
                    //extra space is just for alignment purpose
                    countryName += CCPCountry.getFlagEmoji(ccpCountry) + "   ";
                }

                countryName += ccpCountry.getName();

                boolean isProbablyArabic = isProbablyArabic(countryName);

                if (codePicker.getCcpDialogShowNameCode()) {
                    countryName += " (" + ccpCountry.getNameCode().toUpperCase() + ")";
                }
                //阿拉伯语言

                if (isProbablyArabic) {
                    textView_name.setTextAlignment(TextAlignment.RIGHT | TextAlignment.VERTICAL_CENTER);
                } else {
                    textView_name.setTextAlignment(TextAlignment.LEFT | TextAlignment.VERTICAL_CENTER);
                }

                textView_name.setText(countryName);
                textView_code.setText("+" + ccpCountry.getPhoneCode());

                if (!codePicker.getCcpDialogShowFlag() || codePicker.ccpUseEmoji) {
                    linearFlagHolder.setVisibility(Component.HIDE);
                } else {
                    linearFlagHolder.setVisibility(Component.VISIBLE);
                    setBoundImage(ccpCountry.getFlagID());
                }
            } else {
                divider.setVisibility(Component.VISIBLE);
                textView_name.setVisibility(Component.HIDE);
                textView_code.setVisibility(Component.HIDE);
                linearFlagHolder.setVisibility(Component.HIDE);
            }
        }

        private void setBoundImage(int flagResID) {

            try {
                int width = linearFlagHolder.getWidth();
                Resource resource = context.getResourceManager().getResource(flagResID);
                ImageSource imageSource = ImageSource.create(resource, null);
                ImageInfo imageInfo = imageSource.getImageInfo();
                Size size = imageInfo.size;
                ImageSource.DecodingOptions opts = new ImageSource.DecodingOptions();
                PixelMap pixelmap = imageSource.createPixelmap(opts);
                PixelMapElement pixelMapElement = new PixelMapElement(pixelmap);
                int boundsBottom = width * size.height / size.width;
                pixelMapElement.setBounds(0, 0, width, boundsBottom);
                imageViewFlag.setImageElement(pixelMapElement);
                ComponentContainer.LayoutConfig layoutConfig = imageViewFlag.getLayoutConfig();
                layoutConfig.width = width;
                layoutConfig.height = boundsBottom;
                imageViewFlag.setLayoutConfig(layoutConfig);
            } catch (Exception e) {
                imageViewFlag.setPixelMap(flagResID);
            }
        }

        private boolean isProbablyArabic(String s) {
            for (int i = 0; i < s.length(); ) {
                int c = s.codePointAt(i);
                if (c >= 0x0600 && c <= 0x06E0)
                    return true;
                i += Character.charCount(c);
            }
            return false;
        }

        public Component getMainView() {
            return relativeLayout_main;
        }
    }
}

